Открыть в приложении

Различные методы семантического сходства предложений в НЛП

Последнее обновление: 17 окт. 2024 г.
Комментарии
Улучшать
Предложить изменения
Нравится статья
Нравиться
Отчет

Семантическое сходство — это сходство между двумя словами или двумя предложениями/фразами/текстом. Оно измеряет, насколько близки или различны два фрагмента слова или текста с точки зрения их значения и контекста.

В этой статье мы сосредоточимся на том, как выводится семантическое сходство между двумя предложениями. Мы рассмотрим следующие наиболее используемые модели.

  1. Dov2Vec — расширение word2vec
  2. SBERT — модель на основе трансформатора, в которой кодирующая часть фиксирует значение слов в предложении.
  3. InferSent — использует двунаправленную LSTM-память для кодирования предложений и выведения семантики.
  4. USE (универсальный кодировщик предложений) — это обученная Google модель, которая генерирует вложения фиксированного размера для предложений, которые можно использовать для любой задачи обработки естественного языка.

Что такое семантическое сходство?

Семантическое сходство относится к степени сходства между словами. Основное внимание уделяется структуре и лексическому сходству слов и фраз. Семантическое сходство углубляется в понимание и значение содержания. Цель сходства — измерить, насколько тесно связаны или аналогичны концепции, идеи или информация, переданные в двух текстах.

В НЛП семантическое сходство используется в различных задачах, таких как

  1. Вопросы и ответы — улучшает систему контроля качества, устанавливая семантическое сходство между запросами пользователей и содержимым документа.
  2. Рекомендательные системы - Семантическое сходство между пользовательским контентом и доступным контентом
  3. Резюмирование — помогает в резюмировании ответов на вопросы по схожему содержанию и сопоставлении текстов.
  4. Кластеризация корпусов — помогает группировать документы со схожим содержанием.

Существуют определенные подходы к измерению семантического сходства в обработке естественного языка (NLP), которые включают в себя встраивание слов, встраивание предложений и модели преобразователя.

Встраивание слов

Чтобы понять семантические связи между предложениями, нужно знать о вложениях слов . Вложения слов используются для векторного представления слов. Простейшая форма вложения слов — это one-hot вектор. Однако они разрежены, очень многомерны и не отражают смысл. Более продвинутая форма состоит из Word2Vec ( skip-gram , cbow ), GloVe и Fasttext, которые фиксируют семантическую информацию в низкомерном пространстве. Пожалуйста, посмотрите на встроенную ссылку, чтобы глубже понять это.

Word2Vec

Word2Vec представляет слова как многомерные векторы, так что мы получаем семантически похожие слова, близкие друг к другу в векторном пространстве. Существуют две основные архитектуры для Word2Vec:

  • Непрерывный мешок слов: цель — предсказать целевое слово на основе контекста окружающих слов.
  • Skip-gram: Модель предназначена для прогнозирования окружающих слов в контексте.

Doc2Vec

Подобно word2vec, Doc2Vec имеет два типа моделей, основанных на skip gram и CBOW. Мы рассмотрим модель на основе skip gram, поскольку она работает лучше, чем модель на основе cbow. Эта модель на основе skip-gram называется ad PV-DM (Distributed Memory Model of Paragraph Vectors) .

Симантическое сходство - Doc2Vec
Модель PV-DM

PV-DM является расширением Word2Vec в том смысле, что он состоит из одного вектора абзаца в дополнение к векторам слов.

  • Вектор абзаца и вектор слова : Предположим, что в корпусе N абзацев и M слов в словаре.
    • Теперь на основе строк word2vec у нас будет матрица M*Q (Q — размерность вложения слов), которая будет нашей матрицей вложения для вложения слов. Кроме того, у нас будет матрица N*P для наших абзацев (p — размерность вложения абзацев).
    • Вектор абзаца является общим для всех контекстов, созданных из одного и того же абзаца, но не для разных абзацев.
    • Матрица векторов слов W является общей для всех абзацев.
  • Усреднение или конкатенация : чтобы предсказать следующее слово в контексте, вектор абзаца и векторы слов объединяются с помощью усреднения или конкатенации.
  • Модель распределенной памяти (PV-DM): токен абзаца действует как память, которая сохраняет информацию о том, чего не хватает в текущем контексте или теме абзаца.
  • Обучение с помощью стохастического градиентного спуска : стохастический градиентный спуск используется для обучения векторов абзацев и векторов слов. Градиент получается с помощью обратного распространения. На каждом шаге стохастического градиентного спуска из случайного абзаца выбирается контекст фиксированной длины, а градиент ошибки вычисляется для обновления параметров модели.
  • Вывод во время прогнозирования : после обучения модели векторы абзацев отбрасываются, и сохраняются только векторы слов и веса softmax.
    • Для нахождения вектора абзаца нового текста Во время прогнозирования выполняется шаг вывода. Это также достигается с помощью градиентного спуска . На этом шаге векторы слов (W) и веса softmax фиксируются, в то время как вектор абзаца изучается с помощью обратного распространения.
    • Для двух предложений, для которых нам нужно найти сходство, получаются два вектора абзацев и на основе сходства между двумя векторами получают сходство между предложениями.

Подводя итог, можно сказать, что сам алгоритм состоит из двух ключевых этапов:

  • Обучение для получения векторов слов W, весов softmax U, b и векторов абзацев D для уже просмотренных абзацев.
  • Этап вывода заключается в получении векторов абзацев D для новых абзацев (ранее не встречавшихся) путем добавления дополнительных столбцов в D и нисходящего градиента на D с удержанием W, U и смешанного.

Мы используем изученные векторы абзацев для прогнозирования некоторых конкретных меток с помощью стандартного классификатора, например, логистической регрессии.

Реализация Doc2Vec на Python

Ниже представлена ​​простая реализация Doc2Vec.

  1. Сначала мы токенизируем слова в каждом документе и преобразуем их в нижний регистр.
  2. Затем мы создаем объекты TaggedDocument, необходимые для обучения модели Doc2Vec. Каждый документ связан с уникальным тегом (идентификатором документа). Это вектор абзаца.
  3. Параметры (vector_size, window, min_count, workers, epochs) управляют размерами модели, размером контекстного окна, минимальным количеством слов, распараллеливанием и эпохами обучения.
  4. Затем мы выводим векторное представление для нового документа, который не был частью обучающих данных.
  5. Затем мы вычисляем показатель сходства.
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
from nltk.tokenize import word_tokenize
import nltk
nltk.download('punkt')

# Sample data
data = ["The movie is awesome. It was a good thriller",
        "We are learning NLP throughg GeeksforGeeks",
        "The baby learned to walk in the 5th month itself"]

# Tokenizing the data
tokenized_data = [word_tokenize(document.lower()) for document in data]

# Creating TaggedDocument objects
tagged_data = [TaggedDocument(words=words, tags=[str(idx)])
               for idx, words in enumerate(tokenized_data)]


# Training the Doc2Vec model
model = Doc2Vec(vector_size=100, window=2, min_count=1, workers=4, epochs=1000)
model.build_vocab(tagged_data)
model.train(tagged_data, total_examples=model.corpus_count,
            epochs=model.epochs)

# Infer vector for a new document
new_document = "The baby was laughing and palying"
print('Original Document:', new_document)

inferred_vector = model.infer_vector(word_tokenize(new_document.lower()))

# Find most similar documents
similar_documents = model.dv.most_similar(
    [inferred_vector], topn=len(model.dv))

# Print the most similar documents
for index, score in similar_documents:
    print(f"Document {index}: Similarity Score: {score}")
    print(f"Document Text: {data[int(index)]}")
    print()

Выход:

Оригинальный документ: Ребенок смеялся и играл 
Документ 2: Оценка сходства: 0,9838361740112305
Текст документа: Ребенок научился ходить на 5-м месяце

Документ 0: Оценка сходства: 0,9455077648162842
Текст документа: Фильм потрясающий. Это был хороший триллер

Документ 1: Оценка сходства: 0,8828089833259583
Текст документа: Мы изучаем НЛП через GeeksforGeeks

СБЕРТ

SBERT добавляет операцию объединения к выходу BERT для получения вложений предложений фиксированного размера. Предложение преобразуется в вложение слов и передается через сеть BERT для получения вектора контекста. Исследователи экспериментировали с различными вариантами объединения, но обнаружили, что в среднем объединение работает лучше всего. Затем вектор контекста усредняется для получения вложений предложений.

SBERT использует три целевые функции для обновления весов модели BERT. Модель Bert структурирована по-разному в зависимости от типа обучающих данных, которые управляют целевой функцией.

1. Классификационная цель Функция

  • Эта архитектура модели использует часть предложения вместе с метками в качестве обучающих данных.
  • Здесь модель Bert структурирована как сиамская сеть. Что такое сиамская сеть? Она состоит из двух идентичных подсетей, каждая из которых является моделью BERT. Две модели разделяют/имеют одинаковые параметры/веса. Обновление параметров зеркально отражается в обеих подмоделях. Наверху слоя опроса у нас есть softmax-классификатор с числом узлов, равным числу меток данных обучения.
  • Предложения передаются вместе, чтобы получить вложения предложений u и v вместе с поэлементно различными |uv|. Эти три вектора (u, v,|uv|) умножаются на весовой вектор W размером (3n*K), чтобы получить классификацию softmax.
    Ц е л ь н ы е ф у н к ц и и =софтмах(ВтТ(ты,в,тыв))\text{Целевые функции} = softmax(W^T(u,v,|uv|))
    Здесь,
    • n — размерность вложений предложений
    • k количество меток.
  • Оптимизация выполняется с использованием потери кросс-энтропии.
Изображение-41
SBERT с функцией объективной классификации

2. Целевая функция регрессии

Это также использует пару предложений с метками в качестве обучающих данных. Сеть также структурирована как сиамская сеть. Однако вместо слоя softmax для вычисления косинусного сходства используется выход слоя объединения, а среднеквадратичная ошибка потерь используется в качестве целевой функции для обучения весов модели BERT.

SBERT с функцией регрессионной цели-Geeksforgeeks
SBERT с целевой функцией регрессии


3. Триплетная целевая функция

Здесь модель структурирована как триплетные сети.

  • В триплетной сети три подсети обрабатывают якорное предложение, положительное (похожее) предложение и отрицательное (несхожее) предложение. Модель учится минимизировать расстояние между якорным и положительным предложениями, одновременно максимизируя расстояние между якорным и отрицательным предложениями.
  • Для обучения модели нам нужен набор данных, который содержит якорный набор данных a, положительное предложение p и отрицательное предложение n. Примером такого набора данных является «Набор данных триплетов раздела Википедии».

Математически мы минимизируем следующую функцию потерь.

мах(саспсасн+ϵ,0)max(||sa − sp|| − ||sa − sn|| + \epsilon, 0)

  • с sa, sp, sn предложение встраивание для a/n/p,
  • || · || метрика расстояния и маржа.
  • Запас ϵ гарантирует, что sp по крайней мере ближе к sa, чем sn.

Реализация Python

Для реализации нам сначала нужно установить фреймворк Sentence transformer.

!pip install -U предложения-трансформеры
  • Класс SentenceTransformer используется для загрузки модели SBERT.
  • Класс SentenceTransformer используется для загрузки модели SBERT.
  • Мы используем косинусное расстояние scipy для вычисления расстояния между двумя векторами. Чтобы получить сходство, мы вычитаем его из 1
#!pip install -U sentence-transformers

from scipy.spatial import distance
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')

# Sample sentence
sentences = ["The movie is awesome. It was a good thriller",
             "We are learning NLP throughg GeeksforGeeks",
             "The baby learned to walk in the 5th month itself"]


test = "I liked the movie."
print('Test sentence:',test)
test_vec = model.encode([test])[0]


for sent in sentences:
    similarity_score = 1-distance.cosine(test_vec, model.encode([sent])[0])
    print(f'\nFor {sent}\nSimilarity Score = {similarity_score} ')

Выход:

Тестовое предложение: Мне понравился фильм. 

Фильм потрясающий. Это был хороший триллер.
Оценка сходства = 0,682051956653595.

Для Мы изучаем НЛП через GeeksforGeeks.
Оценка сходства = 0,0878136083483696.

Для Ребенок научился ходить на 5-м месяце.
Оценка сходства = 0,04816452041268349.

Вывод

Структура состоит из двух компонентов:

Кодировщик предложений

  • Первый — это кодировщик предложений, отвечающий за получение векторов слов и преобразование предложений в закодированные векторы.
  • InferSent начинает с предварительно обученных вложений слов. Слова встраиваются в непрерывные векторные представления.
  • Эти внедрения служат входными данными для двунаправленной LSTM-сети , способной фиксировать последовательную информацию и зависимости в данных.
  • После обработки входного предложения через двунаправленную LSTM применяется слой пулинга для получения векторного представления фиксированного размера всего предложения. Распространенные методы пулинга включают максимальный пул, средний пул или конкатенацию конечных скрытых состояний.

Классификатор

  • Объединенное представление предложений пропускается через один или несколько полностью связанных слоев.
  • Эти слои служат частью классификатора, которая принимает объединенные закодированные векторы в качестве входных данных и генерирует классификацию, определяя, является ли связь между предложениями следствием, противоречием или нейтральной.
  • Для извлечения связей между парами предложений u и v применяются 3 метода сопоставления.
    • конкатенация двух представлений (u, v)
    • поэлементное произведение u * v
    • поэлементная разность |u — v |
  • Полученный вектор подается в 3-классовый классификатор (вывод, противоречие и нейтральность), состоящий из нескольких полностью связанных слоев, за которыми следует слой SoftMax.
Семантическое сходство - выводимое
Обучение кодировщику предложений для классификации

Реализация Python

Реализация выведенной модели — немного длительный процесс, поскольку стандартного API для обнимающего лица не существует. Infersent поставляется в двух версиях. Версия 1 обучается с помощью Glove, а версия 2 — с помощью FastText wordembedding . Мы будем использовать версию 2, поскольку ее загрузка и обработка занимает меньше времени.

Сначала нам нужно построить выводимую модель. Нижеприведенный класс делает это. Он был взят из модели Python Zoo.

Далее мы загружаем самые современные вложения fastText и загружаем предварительно обученные модели.


  • Код загружает модель токенизатора Punkt из NLTK , которая используется для токенизации .
  • Затем мы задаем путь (MODEL_PATH) к файлу предварительно обученной модели InferSent и загружаем ее веса в экземпляр класса InferSent.
  • Указываем путь к нашим вложениям слов (W2V_PATH)
  • Метод build_vocab_k_words вызывается для загрузки вложений для K наиболее часто встречающихся слов (в данном случае — 100 000 самых популярных слов).


Затем мы используем модель для вывода

# Sample sentence
from scipy.spatial import distance
sentences = ["The movie is awesome. It was a good thriller",
             "We are learning NLP throughg GeeksforGeeks",
             "The baby learned to walk in the 5th month itself"]


test = "I liked the movie"
print('Test Sentence:', test)
test_vec = model.encode([test])[0]

for sent in sentences:
    similarity_score = 1-distance.cosine(test_vec, model.encode([sent])[0])
    print(f'\nFor {sent}\nSimilarity Score = {similarity_score} ')

Выход:

Тестовое предложение: Мне понравился фильм 

Фильм потрясающий. Это был хороший триллер
Оценка сходства = 0,5299297571182251

Мы изучаем НЛП через GeeksforGeeks
Оценка сходства = 0,33156681060791016

Ребенок научился ходить на 5-м месяце жизни
Оценка сходства = 0,20128820836544037

USE — универсальный кодировщик предложений

На высоком уровне он состоит из кодировщика, который обобщает любое предложение, чтобы получить вложение предложения, которое можно использовать для любой задачи обработки естественного языка.

Часть кодировщика поставляется в двух вариантах, и любой из них может быть использован

  • Transformer - Здесь используется часть кодировщика оригинальной архитектуры transformer . Архитектура состоит из 6 сложенных слоев transformer. Каждый слой имеет модуль внутреннего внимания, за которым следует сеть прямой связи . Выходные контекстно-зависимые вложения слов добавляются поэлементно и делятся на квадратный корень длины предложения для учета разницы в длине предложения. Мы получаем 512-мерный вектор в качестве выходного вложения предложения.
  • Глубокая усредняющая сеть — вложения для слов и биграмм, присутствующих в предложении, усредняются вместе. Затем они пропускаются через 4-слойную глубокую DNN с прямой связью, чтобы получить 512-мерное вложение предложения в качестве выходных данных. Вложения для слов и биграмм изучаются во время обучения.

Подготовка к ЕГЭ

USE обучается выполнению различных контролируемых и неконтролируемых заданий, таких как Skipthoughts, NLI и других, с использованием следующих принципов.

  • Токенизировать предложения после преобразования их в строчные буквы
  • В зависимости от типа кодировщика предложение преобразуется в 512-мерный вектор.
  • Полученные вложения предложений впоследствии используются для обновления параметров модели.
  • Затем обученная модель снова применяется для создания нового 512-мерного вложения предложения.
Семантическое сходство - Универсальный кодировщик предложений
Обучение кодировщика

Реализация Python

Мы загружаем модуль TF Hub универсального кодировщика предложений.

  • module_url содержит URL-адрес для загрузки универсального кодировщика предложений (версии 4) из TensorFlow Hub.
  • Функция hub.load используется для загрузки модели Universal Sentence Encoder с указанного URL (module_url).
  • Мы определяем функцию с именем embed, которая принимает входной текст и возвращает встраивания, используя загруженную модель универсального кодировщика предложений.
import tensorflow as tf

import tensorflow_hub as hub
import matplotlib.pyplot as plt
import numpy as np
import os
import pandas as pd
import re
import seaborn as sns

module_url = "https://tfhub.dev/google/universal-sentence-encoder/4"
model = hub.load(module_url)
print("module %s loaded" % module_url)


def embed(input):
    return model(input)


Ниже мы рассчитаем степень сходства на основе наших выборочных данных.

from scipy.spatial import distance


test = ["I liked the movie very much"]
print('Test Sentence:',test)
test_vec = embed(test)
# Sample sentence
sentences = [["The movie is awesome and It was a good thriller"],
        ["We are learning NLP throughg GeeksforGeeks"],
        ["The baby learned to walk in the 5th month itself"]]

for sent in sentences:
    similarity_score = 1-distance.cosine(test_vec[0,:],embed(sent)[0,:])
    print(f'\nFor {sent}\nSimilarity Score = {similarity_score} ')

Выход

Тестовое предложение: ['Мне очень понравился фильм'] 

Для ['Фильм потрясающий, и это был хороший триллер']
Оценка сходства = 0,6519516706466675

Для ['Мы изучаем НЛП с помощью GeeksforGeeks']
Оценка сходства = 0,06988027691841125

Для ['Ребенок научился ходить на 5-м месяце']
Оценка сходства = -0,01121298223733902

Заключение

В этой статье мы разобрались с семантическим сходством и его применением. Мы увидели архитектуру 4 лучших моделей встраивания предложений, используемых для расчета семантического сходства предложений, и их реализацию на Python.


Следующая статья

Похожие чтения

Исходный текст
Оцените этот перевод
Ваш отзыв поможет нам улучшить Google Переводчик